package com.anlu.base.reflection;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;

class GenericClass<T,U> {
    // 这里可以定义与泛型相关的方法和属性

    private T myValue;

    private T value1;
    private U value2;

    private List<String> students;

    private List<T> teachers;


    T get(Integer age) {
        return null;
    }

}

public class GenericTypeExample {

    private static final Logger logger = LoggerFactory.getLogger(GenericTypeExample.class);

    public static void main(String[] args) {

//        test();
//        test1();
        test2();
//        test3();
    }

    static void test() {
        //获取GenericClass的父类类型
        Type type = GenericClass.class.getGenericSuperclass();

        if(type instanceof TypeVariable){
            logger.info("type.name={}",type.getTypeName());
        }

        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            //获取泛型类型参数
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument.getTypeName());
            }
        }
    }

    static void test1() {
        try {
            // 获取 MyGenericClass 类的 Class 对象
            Class<?> clazz = GenericClass.class;

            // 获取指定字段
            Field field = clazz.getDeclaredField("myValue");

            // 获取字段的类型
            Type type = field.getGenericType();

            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                // 获取实际的泛型类型
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument.getTypeName());
                }
            }
        } catch (NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
    }

    static void test2(){
        try{
            Class<?> clazz = GenericClass.class;
            Field[] fields = clazz.getDeclaredFields();
            for(Field field : fields){
                Type type = field.getGenericType();
                if(type instanceof ParameterizedType){
                    ParameterizedType parameterizedType = (ParameterizedType) type;
                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                    for (Type actualTypeArgument : actualTypeArguments) {
                        System.out.println("泛型参数名称: " + actualTypeArgument.getTypeName());
                    }
                }
            }
        } catch (Exception e){

        }
    }

    static void test3(){
        List<String> list = new ArrayList<>();
        Type type = list.getClass().getGenericSuperclass();
        if(type instanceof ParameterizedType){
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            System.out.println("Actual type argument: " + actualTypeArguments[0]);
        }
    }
}
